package com.agile.leetcode.concurrent.transmittable;


import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.TtlCallable;
import com.alibaba.ttl.TtlRunnable;
import com.alibaba.ttl.threadpool.TtlExecutors;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * TransmittableThreadLocal的引入
 *
 * @Author:ChenZhangKun
 * @Date: 2021/10/24 22:13
 */
public class TransmitTableDemo {
    // 定义可继承变量的线程
    private static final InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>();
    private static final ThreadLocal<String> threadLocal = new ThreadLocal<>();
    private static final ExecutorService threadExecutor = Executors.newFixedThreadPool(3);
    // alibaba提供，解决线程池复用的线程变量继承问题
    private static final TransmittableThreadLocal<String> context = new TransmittableThreadLocal<>();

    public static void main(String[] args) {
        demo1();
        demo3();
        demo4();
        demo5();
        demo6();
    }

    public static void demo1() {
        threadLocal.set("nzq");
        new Thread(() -> {
            // null
            System.out.println(threadLocal.get());
        }).start();
    }

    public static void demo2() {
        inheritableThreadLocal.set("czk");
        // 新开线程
        new Thread(() -> {
            // czk->可继承
            // 但是无法解决线程池复用的问题
            System.out.println(inheritableThreadLocal.get());
        }).start();
    }

    public static void demo3() {
        inheritableThreadLocal.set("james");
        threadExecutor.execute(() -> {
            System.out.println(inheritableThreadLocal.get());
        });
    }

    /**
     * 修饰runnable的方式
     */
    public static void demo4() {
        context.set("kd");
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println(context.get());
            }
        };
        // 修饰
        TtlRunnable ttlRunnable = TtlRunnable.get(runnable);
        // 提交任务
        threadExecutor.execute(ttlRunnable);
    }

    /**
     * 修饰callable的方式
     */
    public static void demo5() {
        context.set("kd");
        TtlCallable<String> ttlCallable = TtlCallable.get(() -> {
            System.out.println(context.get());
            return "ok";
        });
        // 提交任务
        threadExecutor.submit(ttlCallable);
    }

    /**
     * 修饰线程池的方式
     */
    public static void demo6() {
        ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(threadExecutor);
        //
        context.set("AD");
        // 提交callAble
        ttlExecutorService.submit(() -> {
            System.out.println(context.get());
            return "ok";
        });
        // 提交runnable
        ttlExecutorService.submit(() -> {
            System.out.println(context.get());
        });
    }
}
